/*
* Draw.java
* Copyright (C) 2003
*
* $Id: Draw.java,v 1.3 2005/11/21 21:16:58 cawe Exp $
*/
/*
Copyright (C) 1997-2001 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
using System;
using Defines = Suake2.UI.Defines;
using VID = Suake2.UI.client.VID;
using Com = Suake2.UI.qcommon.Com;
using image_t = Suake2.UI.render.image_t;
using Lib = Suake2.UI.util.Lib;
//UPGRADE_TODO: The type 'java.nio.ByteBuffer' could not be found. If it was not included in the conversion, there may be compiler issues. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1262'"
using ByteBuffer = java.nio.ByteBuffer;
//UPGRADE_TODO: The type 'java.nio.IntBuffer' could not be found. If it was not included in the conversion, there may be compiler issues. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1262'"
using IntBuffer = java.nio.IntBuffer;
using BufferUtils = org.lwjgl.BufferUtils;
using GL11 = org.lwjgl.opengl.GL11;
namespace Suake2.UI.render.lwjgl
{
	
	/// <summary> Draw
	/// (gl_draw.c)
	/// 
	/// </summary>
	/// <author>  cwei
	/// </author>
	public abstract class Draw:Image
	{
		public Draw()
		{
			InitBlock();
		}
		private void  InitBlock()
		{
			image8 = Lib.newByteBuffer(256 * 256 * Defines.SIZE_OF_INT);
			image32 = image8.asIntBuffer();
		}
		
		/*
		===============
		Draw_InitLocal
		===============
		*/
		internal override void  Draw_InitLocal()
		{
			// load console characters (don't bilerp characters)
			draw_chars = GL_FindImage("pics/conchars.pcx", it_pic);
			GL_Bind(draw_chars.texnum);
			gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
			gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
		}
		
		/*
		================
		Draw_Char
		
		Draws one 8*8 graphics character with 0 being transparent.
		It can be clipped to the top of the screen to allow the console to be
		smoothly scrolled off.
		================
		*/
		protected internal virtual void  Draw_Char(int x, int y, int num)
		{
			
			num &= 255;
			
			if ((num & 127) == 32)
				return ; // space
			
			if (y <= - 8)
				return ; // totally off screen
			
			int row = num >> 4;
			int col = num & 15;
			
			float frow = row * 0.0625f;
			float fcol = col * 0.0625f;
			float size = 0.0625f;
			
			GL_Bind(draw_chars.texnum);
			
			gl.glBegin(GL11.GL_QUADS);
			gl.glTexCoord2f(fcol, frow);
			gl.glVertex2f(x, y);
			gl.glTexCoord2f(fcol + size, frow);
			gl.glVertex2f(x + 8, y);
			gl.glTexCoord2f(fcol + size, frow + size);
			gl.glVertex2f(x + 8, y + 8);
			gl.glTexCoord2f(fcol, frow + size);
			gl.glVertex2f(x, y + 8);
			gl.glEnd();
		}
		
		
		/*
		=============
		Draw_FindPic
		=============
		*/
		protected internal virtual image_t Draw_FindPic(System.String name)
		{
			image_t image = null;
			System.String fullname;
			
			if (!name.StartsWith("/") && !name.StartsWith("\\"))
			{
				fullname = "pics/" + name + ".pcx";
				image = GL_FindImage(fullname, it_pic);
			}
			else
			{
				image = GL_FindImage(name.Substring(1), it_pic);
			}
			return image;
		}
		
		
		/*
		=============
		Draw_GetPicSize
		=============
		*/
		//UPGRADE_NOTE: ref keyword was added to struct-type parameters. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1303'"
		protected internal virtual void  Draw_GetPicSize(ref System.Drawing.Size dim, System.String pic)
		{
			
			image_t image = Draw_FindPic(pic);
			dim.Width = (image != null)?image.width:- 1;
			dim.Height = (image != null)?image.height:- 1;
		}
		
		/*
		=============
		Draw_StretchPic
		=============
		*/
		protected internal virtual void  Draw_StretchPic(int x, int y, int w, int h, System.String pic)
		{
			
			image_t image;
			
			image = Draw_FindPic(pic);
			if (image == null)
			{
				VID.Printf(Defines.PRINT_ALL, "Can't find pic: " + pic + '\n');
				return ;
			}
			
			if (scrap_dirty)
				Scrap_Upload();
			
			if (((gl_config.renderer == GL_RENDERER_MCD) || ((gl_config.renderer & GL_RENDERER_RENDITION) != 0)) && !image.has_alpha)
				gl.glDisable(GL11.GL_ALPHA_TEST);
			
			GL_Bind(image.texnum);
			gl.glBegin(GL11.GL_QUADS);
			gl.glTexCoord2f(image.sl, image.tl);
			gl.glVertex2f(x, y);
			gl.glTexCoord2f(image.sh, image.tl);
			gl.glVertex2f(x + w, y);
			gl.glTexCoord2f(image.sh, image.th);
			gl.glVertex2f(x + w, y + h);
			gl.glTexCoord2f(image.sl, image.th);
			gl.glVertex2f(x, y + h);
			gl.glEnd();
			
			if (((gl_config.renderer == GL_RENDERER_MCD) || ((gl_config.renderer & GL_RENDERER_RENDITION) != 0)) && !image.has_alpha)
				gl.glEnable(GL11.GL_ALPHA_TEST);
		}
		
		
		/*
		=============
		Draw_Pic
		=============
		*/
		protected internal virtual void  Draw_Pic(int x, int y, System.String pic)
		{
			image_t image;
			
			image = Draw_FindPic(pic);
			if (image == null)
			{
				VID.Printf(Defines.PRINT_ALL, "Can't find pic: " + pic + '\n');
				return ;
			}
			if (scrap_dirty)
				Scrap_Upload();
			
			if (((gl_config.renderer == GL_RENDERER_MCD) || ((gl_config.renderer & GL_RENDERER_RENDITION) != 0)) && !image.has_alpha)
				gl.glDisable(GL11.GL_ALPHA_TEST);
			
			GL_Bind(image.texnum);
			
			gl.glBegin(GL11.GL_QUADS);
			gl.glTexCoord2f(image.sl, image.tl);
			gl.glVertex2f(x, y);
			gl.glTexCoord2f(image.sh, image.tl);
			gl.glVertex2f(x + image.width, y);
			gl.glTexCoord2f(image.sh, image.th);
			gl.glVertex2f(x + image.width, y + image.height);
			gl.glTexCoord2f(image.sl, image.th);
			gl.glVertex2f(x, y + image.height);
			gl.glEnd();
			
			if (((gl_config.renderer == GL_RENDERER_MCD) || ((gl_config.renderer & GL_RENDERER_RENDITION) != 0)) && !image.has_alpha)
				gl.glEnable(GL11.GL_ALPHA_TEST);
		}
		
		/*
		=============
		Draw_TileClear
		
		This repeats a 64*64 tile graphic to fill the screen around a sized down
		refresh window.
		=============
		*/
		protected internal virtual void  Draw_TileClear(int x, int y, int w, int h, System.String pic)
		{
			image_t image;
			
			image = Draw_FindPic(pic);
			if (image == null)
			{
				VID.Printf(Defines.PRINT_ALL, "Can't find pic: " + pic + '\n');
				return ;
			}
			
			if (((gl_config.renderer == GL_RENDERER_MCD) || ((gl_config.renderer & GL_RENDERER_RENDITION) != 0)) && !image.has_alpha)
				gl.glDisable(GL11.GL_ALPHA_TEST);
			
			GL_Bind(image.texnum);
			gl.glBegin(GL11.GL_QUADS);
			gl.glTexCoord2f(x / 64.0f, y / 64.0f);
			gl.glVertex2f(x, y);
			gl.glTexCoord2f((x + w) / 64.0f, y / 64.0f);
			gl.glVertex2f(x + w, y);
			gl.glTexCoord2f((x + w) / 64.0f, (y + h) / 64.0f);
			gl.glVertex2f(x + w, y + h);
			gl.glTexCoord2f(x / 64.0f, (y + h) / 64.0f);
			gl.glVertex2f(x, y + h);
			gl.glEnd();
			
			if (((gl_config.renderer == GL_RENDERER_MCD) || ((gl_config.renderer & GL_RENDERER_RENDITION) != 0)) && !image.has_alpha)
				gl.glEnable(GL11.GL_ALPHA_TEST);
		}
		
		
		/*
		=============
		Draw_Fill
		
		Fills a box of pixels with a single color
		=============
		*/
		protected internal virtual void  Draw_Fill(int x, int y, int w, int h, int colorIndex)
		{
			
			if (colorIndex > 255)
				Com.Error(Defines.ERR_FATAL, "Draw_Fill: bad color");
			
			gl.glDisable(GL11.GL_TEXTURE_2D);
			
			int color = d_8to24table[colorIndex];
			
			gl.glColor3ub((sbyte) ((color >> 0) & 0xff), (sbyte) ((color >> 8) & 0xff), (sbyte) ((color >> 16) & 0xff));
			
			gl.glBegin(GL11.GL_QUADS);
			
			gl.glVertex2f(x, y);
			gl.glVertex2f(x + w, y);
			gl.glVertex2f(x + w, y + h);
			gl.glVertex2f(x, y + h);
			
			gl.glEnd();
			gl.glColor3f(1, 1, 1);
			gl.glEnable(GL11.GL_TEXTURE_2D);
		}
		
		//=============================================================================
		
		/*
		================
		Draw_FadeScreen
		================
		*/
		protected internal virtual void  Draw_FadeScreen()
		{
			gl.glEnable(GL11.GL_BLEND);
			gl.glDisable(GL11.GL_TEXTURE_2D);
			gl.glColor4f(0, 0, 0, 0.8f);
			gl.glBegin(GL11.GL_QUADS);
			
			gl.glVertex2f(0, 0);
			gl.glVertex2f(vid.width, 0);
			gl.glVertex2f(vid.width, vid.height);
			gl.glVertex2f(0, vid.height);
			
			gl.glEnd();
			gl.glColor4f(1, 1, 1, 1);
			gl.glEnable(GL11.GL_TEXTURE_2D);
			gl.glDisable(GL11.GL_BLEND);
		}
		
		// ====================================================================
		
		// allocate a 256 * 256 texture buffer
		//UPGRADE_NOTE: The initialization of  'image8' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		private ByteBuffer image8;
		// share the buffer
		//UPGRADE_NOTE: The initialization of  'image32' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
		private IntBuffer image32;
		
		/*
		=============
		Draw_StretchRaw
		=============
		*/
		protected internal virtual void  Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, sbyte[] data)
		{
			int i, j, trows;
			int sourceIndex;
			int frac, fracstep;
			float hscale;
			int row;
			float t;
			
			GL_Bind(0);
			
			if (rows <= 256)
			{
				hscale = 1;
				trows = rows;
			}
			else
			{
				hscale = rows / 256.0f;
				trows = 256;
			}
			t = rows * hscale / 256;
			
			if (!qglColorTableEXT)
			{
				//int[] image32 = new int[256*256];
				image32.clear();
				int destIndex = 0;
				
				for (i = 0; i < trows; i++)
				{
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					row = (int) (i * hscale);
					if (row > rows)
						break;
					sourceIndex = cols * row;
					destIndex = i * 256;
					fracstep = cols * 0x10000 / 256;
					frac = fracstep >> 1;
					for (j = 0; j < 256; j++)
					{
						image32.put(destIndex + j, r_rawpalette[data[sourceIndex + (frac >> 16)] & 0xff]);
						frac += fracstep;
					}
				}
				gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, gl_tex_solid_format, 256, 256, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, image32);
			}
			else
			{
				//byte[] image8 = new byte[256*256];
				image8.clear();
				int destIndex = 0; ;
				
				for (i = 0; i < trows; i++)
				{
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					row = (int) (i * hscale);
					if (row > rows)
						break;
					sourceIndex = cols * row;
					destIndex = i * 256;
					fracstep = cols * 0x10000 / 256;
					frac = fracstep >> 1;
					for (j = 0; j < 256; j++)
					{
						image8.put(destIndex + j, data[sourceIndex + (frac >> 16)]);
						frac += fracstep;
					}
				}
				
				gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, 256, 256, 0, GL11.GL_COLOR_INDEX, GL11.GL_UNSIGNED_BYTE, image8);
			}
			gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
			gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
			
			if ((gl_config.renderer == GL_RENDERER_MCD) || ((gl_config.renderer & GL_RENDERER_RENDITION) != 0))
				gl.glDisable(GL11.GL_ALPHA_TEST);
			
			gl.glBegin(GL11.GL_QUADS);
			gl.glTexCoord2f(0, 0);
			gl.glVertex2f(x, y);
			gl.glTexCoord2f(1, 0);
			gl.glVertex2f(x + w, y);
			gl.glTexCoord2f(1, t);
			gl.glVertex2f(x + w, y + h);
			gl.glTexCoord2f(0, t);
			gl.glVertex2f(x, y + h);
			gl.glEnd();
			
			if ((gl_config.renderer == GL_RENDERER_MCD) || ((gl_config.renderer & GL_RENDERER_RENDITION) != 0))
				gl.glEnable(GL11.GL_ALPHA_TEST);
		}
	}
}